<template>
<div class="canvasFlyLine">
  <canvas id="canvas" width="600" height="600"></canvas>
</div>
</template>

<script setup>
import { onMounted, shallowRef } from "vue";

const ctx = shallowRef()


let offset = 2
let rqa = null //动画执行主体
const interval = 80 //动画执行间隔
let nowTime = new Date().getTime()

//虚线长度为10，间距为5
const draw = () => {
  const canvas = document.getElementById('canvas')
  window.cancelAnimationFrame(rqa)
  const pointsList = splitDistanceIntoSegments({x:100,y:300},{x:320,y:300},10,10)
  const lineList = pointsList.map((item, index) => {
    return {
      originX: item.x,
      originY: item.y,
      destinationX: pointsList[index + 1] ? pointsList[index + 1].x : item.x,
      destinationY: pointsList[index + 1] ? pointsList[index + 1].y : item.y
    };
  });
  function animate() {
    if (new Date().getTime() - nowTime > interval) {
      // offset += 0.5
      // if (offset > 200) offset = 0
      canvas.width = 600
      canvas.height = 600

      ctx.value.lineWidth = 10
      ctx.value.strokeStyle = '#ffffff'
      ctx.value.save()
      ctx.value.beginPath()
      ctx.value.moveTo(80, 300)
      ctx.value.lineTo( 320, 300)
      ctx.value.lineJoin = 'round'
      ctx.value.stroke()
      ctx.value.restore()

      lineList.forEach(d => {
        if(d.destinationX  >= 320){
          d.originX = 80
          d.destinationX = 100
        }else{
          d.originX = d.originX + offset
          d.destinationX = d.destinationX + offset
        }
      })
      lineList.forEach(d => {
        const gradient = ctx.value.createLinearGradient(d.originX , 300, d.destinationX, 300);
        gradient.addColorStop(0, '#ffffff');
        gradient.addColorStop(0.2, 'rgba(255,255,255,.5)');
        gradient.addColorStop(1, '#e60012');
        ctx.value.strokeStyle = gradient
        ctx.value.lineWidth = 4
        ctx.value.save()
        ctx.value.beginPath()
        ctx.value.moveTo(d.originX, 300)
        ctx.value.lineTo( d.destinationX, 300)
        ctx.value.lineJoin = 'round'
        ctx.value.stroke()
        ctx.value.restore()
      });


      ctx.value.lineWidth = 10
      ctx.value.strokeStyle = '#f1f1f1'
      ctx.value.save()
      ctx.value.beginPath()
      ctx.value.moveTo(80, 300)
      ctx.value.lineTo( 100, 300)
      ctx.value.lineJoin = 'round'
      ctx.value.stroke()
      ctx.value.restore()
      ctx.value.lineWidth = 10
      ctx.value.strokeStyle = '#f1f1f1'
      ctx.value.save()
      ctx.value.beginPath()
      ctx.value.moveTo(300, 300)
      ctx.value.lineTo( 320, 300)
      ctx.value.lineJoin = 'round'
      ctx.value.stroke()
      ctx.value.restore()
      nowTime = new Date().getTime()
    }
    rqa = window.requestAnimationFrame(animate)
  }
  animate()
}


const splitDistanceIntoSegments = (pointA, pointB, segmentLength, spaceBetween) => {
  // 计算两点之间的向量
  const dx = pointB.x - pointA.x;
  const dy = pointB.y - pointA.y;

  // 总距离
  const totalDistance = Math.sqrt(dx * dx + dy * dy);

  // 确保线段长度和间距是整数，并计算可放置的线段数量（包括起始点）
  const scalableSegmentLength = Math.ceil(segmentLength);
  const scalableSpaceBetween = Math.ceil(spaceBetween);
  const totalScalableLength = scalableSegmentLength + scalableSpaceBetween;
  const scalableTotalDistance = Math.ceil(totalDistance);
  const segmentCount = Math.floor((scalableTotalDistance - scalableSegmentLength) / totalScalableLength) + 1;

  if (segmentCount <= 0) return [];

  const segments = [];
  let currentX = pointA.x;
  let currentY = pointA.y;

  for (let i = 0; i < segmentCount; i++) {
    segments.push({ x: Math.round(currentX), y: Math.round(currentY) });

    // 根据线段长度和间距移动到下一个点
    currentX += Math.round((dx / totalDistance) * scalableSegmentLength);
    currentY += Math.round((dy / totalDistance) * scalableSegmentLength);

    // 添加间距
    if (i < segmentCount - 1) {
      currentX += Math.round((dx / totalDistance) * scalableSpaceBetween);
      currentY += Math.round((dy / totalDistance) * scalableSpaceBetween);
    }
  }

  // 确保最后一个点为pointB
  segments.push({ x: pointB.x, y: pointB.y });

  return segments;
}



onMounted(() => {
  const canvas = document.getElementById("canvas");
  ctx.value = canvas.getContext("2d");
  draw()
})
</script>

<style scoped lang="scss">
.canvasFlyLine{
  display: flex;
  #canvas{
    background: #f1f1f1;
    margin:auto;
  }
}
</style>